package com.ouroboroswiki.core.content.xml.repo.list;

import java.util.Collection;
import java.util.Map;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.TransformerFactory;

import org.w3c.dom.Document;
import org.w3c.dom.Element;

import com.ouroboroswiki.core.AbstractContentRepository;
import com.ouroboroswiki.core.Content;
import com.ouroboroswiki.core.ContentException;
import com.ouroboroswiki.core.ContentPath;
import com.ouroboroswiki.core.ContentRepository;
import com.ouroboroswiki.core.ContentRepositoryFactory;
import com.ouroboroswiki.core.ListableContentRepository;
import com.ouroboroswiki.core.Version;
import com.ouroboroswiki.core.VersionBuilder;
import com.ouroboroswiki.core.WritableContentRepository;
import com.ouroboroswiki.core.content.xml.XMLDOMContent;

public class XMLListContentRepositories extends AbstractContentRepository {
	
	public static final String ROOT_ELEMENT = "repositories";
	public static final String REPO_ELEMENT = "repository";
	public static final String ATTRIBUTE_NAME = "name";
	public static final String ATTRIBUTE_WRITABLE = "writable";
	public static final String ATTRIBUTE_LISTABLE = "listable";

	private ContentRepositoryFactory repositoryFactory;
	private TransformerFactory transformerFactory;
	private DocumentBuilderFactory documentBuilderFactory;
	
	public XMLListContentRepositories( 
			TransformerFactory transformerFactory,
			DocumentBuilderFactory documentBuilderFactory
	) {
		this.transformerFactory = transformerFactory;
		this.documentBuilderFactory = documentBuilderFactory;
	}
	
	public ContentRepositoryFactory getRepositoryFactory() {
		return repositoryFactory;
	}

	public void setRepositoryFactory(ContentRepositoryFactory repositoryFactory) {
		this.repositoryFactory = repositoryFactory;
	}



	@Override
	public Content getContent(Object principal, ContentPath path,
			Version version, Map<String, Object> properties)
			throws ContentException {
		DocumentBuilder documentBuilder;
	
		try {
			 documentBuilder = documentBuilderFactory.newDocumentBuilder();
		} catch (ParserConfigurationException ex) {
			throw new ContentException( "unable to create document builder", ex);
		}
		Document document = documentBuilder.newDocument();
		
		Element root = document.createElement(ROOT_ELEMENT);
		document.appendChild(root);
		
		Collection<ContentRepository> repositories = this.repositoryFactory.getRepositories();
		
		for( ContentRepository repository : repositories  ) {			
			root.appendChild( createElement(document, repository));
		}
		
		XMLDOMContent result = new XMLDOMContent(document, transformerFactory);
		result.setUniqueName("");
		result.setRepositoryName(this.getName());
		result.setAutoIndent(true);
		return result;
	}

	private Element createElement( Document document, ContentRepository repository ) {
		Element repoElement = document.createElement(REPO_ELEMENT);
		String name = repository.getName();
		repoElement.setAttribute(ATTRIBUTE_NAME, name);
		if( repository instanceof ListableContentRepository ) {
			repoElement.setAttribute(ATTRIBUTE_LISTABLE, Boolean.TRUE.toString());
		}
		if( repository instanceof WritableContentRepository ) {
			repoElement.setAttribute(ATTRIBUTE_WRITABLE, Boolean.TRUE.toString());			
		}
		repoElement.setTextContent(repository.getDescription());
		return repoElement;
	}
	
	@Override
	public boolean exists(Object principal, ContentPath path)
			throws ContentException {
		return true;
	}

	@Override
	public Version buildVersion(Object principal, ContentPath path,
			String[] versionPath, VersionBuilder versionBuilder)
			throws ContentException {
		return null;
	}

}
